import { friendData, ApprovingEnum, PullTypeEnum } from "../util/friendData";
import { GCtrl } from "../util/GCtrl";
import { ModifyGroupEnum } from "../util/groupData";

export class GroupVerifyData {
    private constructor() {
        this.onEvent();
    };
    private static m_pInstance: GroupVerifyData = null;
    public static getInstance() {
        if (!this.m_pInstance) {
            this.m_pInstance = new GroupVerifyData();
        }
        return this.m_pInstance;
    }

    private groupVerifyDataArr: any = {};//{'groupId': {'userId': {userData, req_info}}}
    private newGroupNum: number = 0;
    private isCheckedList: any = {};
    private isDoList: any = {};
    private verifyNum: number = 0;

    public static readonly GET_ALL_GROUP_VERIFY = -10000;

    // 群请求 req_info
    // message GroupRequest {
    //     required int32 timestamp      = 1;  // 时间戳
    //     required int32 request_id     = 2;  // 申请者ID
    //     required SourceEnum source    = 3;  // 来源信息
    //     required ApprovingEnum status = 4;  // 审批状态
    //     required int32 approving_id   = 5;  // 处理人ID
    //     required int32 gid            = 6;  // 群ID
    // }
    private onEvent() {
        GCtrl.eventIndex['ServerNtc_GroupVerifyData'] = cc.vv.eventCustom.on("ServerNtc", this.serverNtc.bind(this));
        GCtrl.eventIndex['logout_gvd'] = cc.vv.eventCustom.on('logout', this.logout.bind(this), this);
        GCtrl.eventIndex['updateGroupDataSuccess_GroupVerifyData'] = cc.vv.eventCustom.on("updateGroupDataSuccess", this.updateGroupDataSuccess.bind(this));
    }
    private offEvent() {
        GCtrl.eventIndex['logout_gvd'] && (cc.vv.eventCustom.off('logout', GCtrl.eventIndex['logout_gvd']), delete GCtrl.eventIndex['logout_gvd']);
        GCtrl.eventIndex['ServerNtc_GroupVerifyData'] && cc.vv.eventCustom.off("ServerNtc", GCtrl.eventIndex['ServerNtc_GroupVerifyData']);
        delete GCtrl.eventIndex['ServerNtc_GroupVerifyData'];
        GCtrl.eventIndex['updateGroupDataSuccess_GroupVerifyData'] && (cc.vv.eventCustom.off('updateGroupDataSuccess', GCtrl.eventIndex['updateGroupDataSuccess_GroupVerifyData']), delete GCtrl.eventIndex['updateGroupDataSuccess_GroupVerifyData']);
    }
    private serverNtc(data: any) {
        if (!data) return;
        if (!data.length || data.length == 0) return;
        else {
            let new_req_g_arr = data[0].grp_req;
            //新的群申请消息
            if (new_req_g_arr && new_req_g_arr.length) {
                for (let i in new_req_g_arr) {
                    let new_req_g = new_req_g_arr[i];
                    this.addReqInfo(new_req_g);
                }
            }
        }
    }
    private addReqInfo(reqInfo: any, userData: friendData = null) {
        if (!reqInfo) return false;
        let reqData = { req_info: reqInfo, userData: userData };
        this.groupVerifyDataArr[reqInfo.gid] || (this.groupVerifyDataArr[reqInfo.gid] = {});
        if (reqInfo.status != ApprovingEnum.DELETE) {

            let oldReqInfo = this.groupVerifyDataArr[reqInfo.gid][reqInfo.request_id];
            let oldCheck: boolean = this.isChecked(reqInfo.gid, reqInfo.request_id);

            this.updateReqDataStatus(reqInfo.gid, reqInfo.request_id, reqInfo.status);
            // 新旧请求对应不同提醒判断
            if (!oldReqInfo) {
                this.setVerifyNum(this.verifyNum + 1);
                !this.isChecked(reqInfo.gid, reqInfo.request_id) && this.setNewGroupNum(this.newGroupNum + 1);
            }
            else {
                oldCheck && !this.isChecked(reqInfo.gid, reqInfo.request_id) && this.setNewGroupNum(this.newGroupNum + 1);
            }
            this.groupVerifyDataArr[reqInfo.gid][reqInfo.request_id] = reqData;
        }
        return true;
    }
    private updateReqUserInfo(userData: friendData) {
        if (!userData) return false;
        for (let i in this.groupVerifyDataArr) {
            if (this.groupVerifyDataArr[i][userData.Id]) {
                this.groupVerifyDataArr[i][userData.Id].userData = userData;
            }
        }
        return true;
    }
    private updateReqDataStatus(groupId: number, reqId: number, status: number) {
        if (!groupId || !reqId) return false;
        this.isCheckedList[groupId] || (this.isCheckedList[groupId] = {});
        this.isDoList[groupId] || (this.isDoList[groupId] = {});
        switch (status) {
            case ApprovingEnum.INIT: {
                this.isCheckedList[groupId][reqId] = false;
                this.isDoList[groupId][reqId] = null;
            } break;
            case ApprovingEnum.READ: {
                this.isCheckedList[groupId][reqId] = true;
                this.isDoList[groupId][reqId] = null;
            } break;
            case ApprovingEnum.AGREE: {
                this.isCheckedList[groupId][reqId] = true;
                this.isDoList[groupId][reqId] = true;
            } break;
            case ApprovingEnum.REJECT: {
                this.isCheckedList[groupId][reqId] = true;
                this.isDoList[groupId][reqId] = false;
            } break;
            case ApprovingEnum.DELETE: { } break;
        }
        return true;
    }
    private logout() {
        this.groupVerifyDataArr = {};
        this.newGroupNum = 0;
        this.isCheckedList = {};
        this.isDoList = {};
        GroupVerifyData.m_pInstance = null;
        this.offEvent();
    }
    private requestData(msgType: string, msg: any, callback = null, ...args)//
    {
        cc.vv.GLUtils.sendRequest(msgType, msg, function (error, data) {
            if (data.errorcode) {
                cc.vv.GLUtils.showTips(data.errordes);
            } else {
                callback && callback(data, ...args);
            }
        }.bind(this));
    }
    private updateGroupDataSuccess(data) {
        let groupId = data[0];
        data = data[1];
        let verifyInfo = this.getData(groupId);
        if (!verifyInfo) return false;
        let type = data.type;
        let userData = data.data;
        switch (type) {
            case ModifyGroupEnum.MEMBER_ADD: {
                verifyInfo = verifyInfo[userData.Id];
                if (!verifyInfo) return false;
                this.setNewGroupNum(this.newGroupNum - 1);
                this.agreeRequest(groupId, userData.Id);
            } break;
        }
        return true;
    }

    /**
     * 获取所有群或指定群验证消息数据
     * return {userData, req_info}
     * @param eventName 获取数据的事件名
     * @param groupId 群ID
     */
    public getData(groupId: number, eventName: string = '') {
        if (!groupId) return null;
        //获取所有我管理的群的验证消息
        if (groupId == GroupVerifyData.GET_ALL_GROUP_VERIFY) {
            cc.vv.eventCustom.emit(eventName, this.groupVerifyDataArr, true);
            return this.groupVerifyDataArr;
        }
        //获取对应群id的群验证消息('我'是管理员以上权限)
        else {
            cc.vv.eventCustom.emit(eventName, this.groupVerifyDataArr[groupId], false);
            return this.groupVerifyDataArr[groupId];
        }
    }
    /**
     * 新请求数据
     * @param reqInfoArr 请求数据数组
     */
    public newVerifyData(reqInfoArr: any[]) {
        if (!reqInfoArr) return false;
        for (let i in reqInfoArr) {
            let new_req_g = reqInfoArr[i];
            this.addReqInfo(new_req_g);
        }
        return true;
    }
    /**
     * 获取请求用户的数据
     * @param reqsId 请求用户ID数组
     * @param callback 回调(获取后传入用户数据数组)
     */
    public getReqUserData(reqsId: number[], callback: Function = null) {
        let req: any[] = [];
        for (let i in reqsId) {
            req.push({
                type: PullTypeEnum.RID,
                user_id: reqsId[i]
            });
        }
        GCtrl.GLUtils.sendRequest("PullUsersInfo", { req }, function (err, data) {
            if (data.errorcode)
                GCtrl.GLUtils.showTips(data.errorcode);
            else {
                let usersInfo: friendData[] = [];
                for (let i in data.res) {
                    let userData = friendData.s2cData(data.res[i].user_info[0]);
                    userData && usersInfo.push(userData);
                    this.updateReqUserInfo(userData);
                }
                callback && callback(usersInfo);
            }
        }.bind(this));
    }
    /**
     * 筛选符合条件的请求数据
     * @param condition 筛选条件
     */
    public shaiXuanData(condition: string = '') {
        if (condition == '') return this.groupVerifyDataArr;
        let _hArr = {};
        let { ...tempArr } = this.groupVerifyDataArr;
        for (let i in tempArr) {
            let groupVerifyData = tempArr[i];
            for (let j in groupVerifyData) {
                let friendData = groupVerifyData[j];
                let name = friendData.name;
                let remarkName = friendData.remarkName + "";
                let id = friendData.Id + "";
                if (name.indexOf(condition) == -1 && remarkName.indexOf(condition) == -1 && id.indexOf(condition) == -1) {
                }
                else {
                    _hArr[j] = friendData;
                }
            }
        }
        return _hArr;
    }
    /**
     * 查看请求
     * @param Id 被查看用户ID
     */
    public checkRequest(groupId: number, Id: number) {
        if (this.isCheckedList[groupId][Id] == void 0) return false;
        this.isCheckedList[groupId][Id] = true;
        this.setNewGroupNum(this.newGroupNum - 1);
        return true;
    }
    /**
     * 用户是否被查看
     * @param Id 用户ID
     */
    public isChecked(groupId: number, Id: number) {
        if (this.isCheckedList[groupId] == void 0) return false;
        return !!this.isCheckedList[groupId][Id];
    }
    /**
     * 用户是否被操作(true同意 false拒绝)
     * @param Id 用户ID
     */
    public isDo(groupId: number, Id: number) {
        return this.isDoList[groupId][Id];
    }
    /**
     * 获取新请求数
     */
    public getNewGroupNum() {
        return this.newGroupNum;
    }
    /**
     * 设置新请求数
     * @param num 
     */
    public setNewGroupNum(num: number) {
        if (num == void 0 || num == null) return false;
        num < 0 && (num = 0);
        this.newGroupNum = num;
        cc.vv.eventCustom.emit('updateNewReqNum');
        return true;
    }
    /**
     * 获取指定群的请求数量
     * @param groupId 群ID
     */
    public getGroupNewReqNum(groupId: number) {
        let verifyData = this.groupVerifyDataArr[groupId];
        if (!verifyData) return 0;
        let num = 0;
        for (let i in verifyData) {
            if (this.isDoList[groupId][i] == null ||
                this.isDoList[groupId][i] == void 0)
                ++num;
        }
        return num;
    }
    /**
     * 同意请求
     * @param groupId 群ID
     * @param Id 用户ID
     */
    public agreeRequest(groupId: number, Id: number) {
        let verifyData = this.groupVerifyDataArr[groupId];
        if (!verifyData) return false;
        let user_req_data = verifyData[Id];
        if (!user_req_data) return false;
        this.isDoList[groupId][Id] = true;
        cc.vv.eventCustom.emit('updateNewReqNum');
        cc.vv.eventCustom.emit('agreeMemberSuccess', Id, groupId);
        return true;
    }
    /**
     * 拒绝请求
     * @param groupId 群ID
     * @param Id 用户ID
     */
    public refuseRequest(groupId: number, Id: number) {
        let verifyData = this.groupVerifyDataArr[groupId];
        if (!verifyData) return false;
        let user_req_data = verifyData[Id];
        if (!user_req_data) return false;
        this.isDoList[groupId][Id] = false;
        cc.vv.eventCustom.emit('updateNewReqNum');
        cc.vv.eventCustom.emit('refuseMemberSuccess', Id, groupId);
        return true;
    }
    /**
     * 移除请求数据
     * @param groupId 群ID
     * @param Id 用户ID
     */
    public RemoveVerifyData(groupId: number, Id: number) {
        let verifyData = this.groupVerifyDataArr[groupId];
        if (!verifyData) return false;
        let user_req_data = verifyData[Id];
        if (!user_req_data) return false;
        delete verifyData[Id];
        delete this.isCheckedList[groupId][Id];
        delete this.isDoList[groupId][Id];
        JSON.stringify(verifyData) == '{}' && delete this.groupVerifyDataArr[groupId];
        JSON.stringify(this.isCheckedList) == '{}' && delete this.isCheckedList[groupId];
        JSON.stringify(this.isDoList) == '{}' && delete this.isDoList[groupId];
        this.newGroupNum > 0 && !this.isChecked(groupId, Id) && this.setNewGroupNum(this.newGroupNum - 1);
        this.setVerifyNum(this.verifyNum - 1);
        this.requestData('GroupApproving', { group_id: groupId, user_id: Id, approving: ApprovingEnum.DELETE });
        cc.vv.eventCustom.emit('removeVerifyDataSuccess', groupId, Id);
    }
    public setVerifyNum(num: number) {
        if (num == void 0) return false;
        num < 0 && (num = 0);
        this.verifyNum = num;
        return true;
    }
    public getVerifyNum() {
        return this.verifyNum;
    }
}